#ifndef __FIXEDFLOAT_H__
#define __FIXEDFLOAT_H__

#include <cmath>
#include <limits>
#include <iostream>

template<int precision>
    struct FixedFloat
    {
        FixedFloat(double input) :
            base_m((input+std::numeric_limits<float>::epsilon()) * pow(10, -1 * precision))
        {
        }

        FixedFloat(int base) :
            base_m(base)
        {
        }

        FixedFloat(const FixedFloat<precision>& fixedFloat) :
            base_m(fixedFloat.base_m)
        {

        }

        FixedFloat<precision>&
        operator =(const FixedFloat<precision>& fixedFloat)
        {
            base_m = fixedFloat.base_m;
        }

        bool
        operator ==(const FixedFloat<precision>& fixedFloat) const
        {
            return base_m == fixedFloat.base_m;
        }

        bool
        operator !=(const FixedFloat<precision>& fixedFloat) const
        {
            return !(*this == fixedFloat);
        }

        bool
        operator >(const FixedFloat<precision>& fixedFloat) const
        {
            return base_m > fixedFloat.base_m;
        }

        bool
        operator <(const FixedFloat<precision>& fixedFloat) const
        {
            return base_m < fixedFloat.base_m;
        }

        bool
        operator >=(const FixedFloat<precision>& fixedFloat) const
        {
            return !(*this < fixedFloat);
        }

        bool
        operator <=(const FixedFloat<precision>& fixedFloat) const
        {
            return !(*this > fixedFloat);
        }

        FixedFloat&
        operator +=(const FixedFloat<precision>& fixedFloat)
        {
            base_m += fixedFloat.base_m;
            return *this;
        }

        FixedFloat&
        operator -=(const FixedFloat<precision>& fixedFloat)
        {
            base_m -= fixedFloat.base_m;
            return *this;
        }

        FixedFloat&
        operator *=(const FixedFloat<precision>& fixedFloat)
        {
            double tmp = base_m * fixedFloat.base_m * pow(10, precision);

            base_m = round(tmp);

            return *this;
        }

        operator double() const
        {
            return base_m * pow(10, precision);
        }


    private:
        int base_m;

    };

template<int precision>
    FixedFloat<precision>
    operator +(const FixedFloat<precision>& fixedFloat1, const FixedFloat<
            precision>& fixedFloat2)
    {
        FixedFloat<precision> fixedFloat = fixedFloat1;
        fixedFloat += fixedFloat2;
        return fixedFloat;
    }

template<int precision>
    FixedFloat<precision>
    operator -(const FixedFloat<precision>& fixedFloat1, const FixedFloat<
            precision>& fixedFloat2)
    {
        FixedFloat<precision> fixedFloat = fixedFloat1;
        fixedFloat -= fixedFloat2;
        return fixedFloat;
    }

template<int precision>
    FixedFloat<precision>
    operator *(const FixedFloat<precision>& fixedFloat1, const FixedFloat<
            precision>& fixedFloat2)
    {
        FixedFloat<precision> fixedFloat = fixedFloat1;
        fixedFloat *= fixedFloat2;
        return fixedFloat;
    }


#endif

